package com.caine.etcd.tool;

import java.io.IOException;
import java.net.*;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * @author create by chenming
 * @version v2.0.0
 * @description 网络监测工具
 * @date 2020/1/8 10:24
 */
public class NetTool {
    private static Pattern ipPattern = Pattern.compile("((25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))");

    /**
     * 监测ip+端口是否可用
     * @param host ip/域名
     * @param port 端口
     * @param timeout 超时时间  单位毫秒
     * @return
     */
    public static boolean isHostConnectable(String host, int port,int timeout) {
        Socket socket = new Socket();
        try {
            socket.connect(new InetSocketAddress(host, port));
            return socket.isConnected();
        } catch (Exception e) {
            return false;
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 检查ip/域名是否可用
     * @param host
     * @param timeOut
     * @return
     */
    public static boolean isHostReachable(String host, Integer timeOut) {
        try {
            return InetAddress.getByName(host).isReachable(timeOut);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取当前服务器ip
     * @return
     */
    public static String getIp() {
        String ip = getLinuxLocalIp();
        //如果通过InetAddress获取不到ip(一般window环境是没有问题的，linux如果没有host可能存在获取不到的情况)或者获取到的ip不合法,那么再通过linux走网卡的方式获取
        if(StringTool.isNullOrEmpty(ip) || !ipPattern.matcher(ip).matches() || ip.contains("0:0:")){
            try {
                InetAddress ipAddress = InetAddress.getLocalHost();
                if(ipAddress != null){
                    ip =  ipAddress.getHostAddress();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ip;
    }

    /**
     * 获取Linux下的IP地址
     * @return IP地址
     * @throws SocketException
     */
    private static String getLinuxLocalIp() {
        String ip = "";
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                String name = intf.getName();
                if (!name.contains("docker") && !name.contains("lo")) {
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if ( !inetAddress.isLinkLocalAddress() && !inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                            String ipaddress = inetAddress.getHostAddress();
                            if (ipPattern.matcher(ipaddress).matches() && !ipaddress.equals("127.0.0.1")) {
                                return ipaddress;
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ip;
    }
}
